package com.ruoyi.web.controller.wxopen;


import com.alibaba.fastjson.JSON;
import com.ruoyi.common.core.controller.BaseController;

import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.UUIDGenerator;
import com.ruoyi.framework.web.service.TokenService;
import com.ruoyi.wechat.open.domain.JwSystemUserJwid;
import com.ruoyi.wechat.open.domain.WxAuthInfo;
import com.ruoyi.wechat.open.domain.WxConfig;
import com.ruoyi.wechat.open.service.IJwSystemUserJwidService;
import com.ruoyi.wechat.open.service.IWxConfigService;
import com.ruoyi.wechat.open.service.WxOpenServiceDemo;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.bean.WxOAuth2UserInfo;
import me.chanjar.weixin.common.bean.oauth2.WxOAuth2AccessToken;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.service.WxOAuth2Service;
import me.chanjar.weixin.mp.api.WxMpService;

import me.chanjar.weixin.mp.bean.result.WxMpUser;
import me.chanjar.weixin.mp.config.WxMpConfigStorage;
import me.chanjar.weixin.open.api.WxOpenMpService;
import me.chanjar.weixin.open.api.impl.WxOpenOAuth2ServiceImpl;
import me.chanjar.weixin.open.bean.auth.WxOpenAuthorizationInfo;
import me.chanjar.weixin.open.bean.auth.WxOpenAuthorizerInfo;
import me.chanjar.weixin.open.bean.result.WxOpenAuthorizerInfoResult;
import me.chanjar.weixin.open.bean.result.WxOpenQueryAuthResult;
import org.apache.http.util.TextUtils;
import org.aspectj.weaver.loadtime.Aj;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

/**
 * @author <a href="https://github.com/007gzs">007</a>
 */
@Slf4j
@AllArgsConstructor
@RestController
@RequestMapping("/wxauthapi")
public class WxApiController extends BaseController {

    private final Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private TokenService tokenService;

    @Autowired
    private IWxConfigService wxConfigService;

    @Autowired
    private IJwSystemUserJwidService jwSystemUserJwidService;

    @Autowired
    private WxOpenServiceDemo wxOpenServiceDemo;


    @GetMapping("/auth/goto_auth_url_show")
    @ResponseBody
    public String gotoPreAuthUrlShow() {
        return "<a href='goto_auth_url?user_id=1&base_api=/prod-api'>go</a>";
    }


    @GetMapping("/auth/get_auth_url_info")
    @ResponseBody
    public AjaxResult getPreAuthUrlInfo(HttpServletRequest request, HttpServletResponse response) {
        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        if (loginUser == null) {
            return AjaxResult.error();
        }
        Long userId = loginUser.getUser().getUserId();
        String host = request.getHeader("host");
        String baseApi = request.getParameter("base_api");
        WxAuthInfo authInfo = new WxAuthInfo("http://" + host + baseApi + "/wxauthapi/auth/goto_auth_url?user_id=" + userId + "&base_api=" + baseApi);
        return AjaxResult.success(authInfo);
    }

    @GetMapping("/auth/goto_auth_url")
    public void gotoPreAuthUrl(HttpServletRequest request, HttpServletResponse response) {
        String host = request.getHeader("host");
        String userId = request.getParameter("user_id");
        String baseApi = request.getParameter("base_api");
        String url = "http://" + host + baseApi + "/wxauthapi/auth/jump?user_id=" + userId;
        try {
            url = wxOpenServiceDemo.getWxOpenComponentService().getPreAuthUrl(url);
            // 添加来源，解决302跳转来源丢失的问题
            response.addHeader("Referer", "http://" + host);
            response.sendRedirect(url);
        } catch (WxErrorException | IOException e) {
            logger.error("gotoPreAuthUrl", e);
            throw new RuntimeException(e);
        }
    }

    @GetMapping("/auth/jump")
    @ResponseBody
    public AjaxResult jump(@RequestParam("user_id") String userId, @RequestParam("auth_code") String authorizationCode) {
        try {
            WxOpenQueryAuthResult queryAuthResult = wxOpenServiceDemo.getWxOpenComponentService().getQueryAuth(authorizationCode);
            logger.info("getQueryAuth", queryAuthResult);

            if (TextUtils.isEmpty(userId)) {
                logger.info("getQueryAuth user_id is null");
                return AjaxResult.error("getQueryAuth User is null");
            }
            //获取授权得到的参数
            WxOpenAuthorizationInfo wxOpenAuthorizationInfo = queryAuthResult.getAuthorizationInfo();
            String appid = wxOpenAuthorizationInfo.getAuthorizerAppid();
            String access_token = wxOpenAuthorizationInfo.getAuthorizerAccessToken();
            String refresh_token = wxOpenAuthorizationInfo.getAuthorizerRefreshToken();
            int expires_in = wxOpenAuthorizationInfo.getExpiresIn();
            List<Integer> func_info = wxOpenAuthorizationInfo.getFuncInfo();

            //获取公众号信息基本信息
            WxOpenAuthorizerInfoResult wxOpenAuthorizerInfoResult = wxOpenServiceDemo.getWxOpenComponentService().getAuthorizerInfo(appid);

            //公众号帐号信息
            WxOpenAuthorizerInfo wxOpenAuthorizerInfo = wxOpenAuthorizerInfoResult.getAuthorizerInfo();


            String jwid = wxOpenAuthorizerInfo.getUserName();

            WxConfig wxConfig = new WxConfig();

            wxConfig.setJwid(jwid);//原始 ID

            wxConfig.setApplicationType("公众号");//应用类型

            wxConfig.setWeixinAppid(appid);//appid
            wxConfig.setAccessToken(access_token);//access_token
            wxConfig.setAuthorizerRefreshToken(refresh_token);//refresh_token

            wxConfig.setFuncInfo(JSON.toJSONString(func_info));//授权权限集合

            wxConfig.setName(wxOpenAuthorizerInfo.getNickName());//昵称
            wxConfig.setPrincipalNname(wxOpenAuthorizerInfo.getPrincipalName());//主体名称
            wxConfig.setHeadimgurl(wxOpenAuthorizerInfo.getHeadImg());//头像
            wxConfig.setAccountType(String.valueOf(wxOpenAuthorizerInfo.getServiceTypeInfo()));//公众号类型 0 订阅 1由历史老帐号升级后的订阅 2 服务号
            wxConfig.setAuthStatus(String.valueOf(wxOpenAuthorizerInfo.getVerifyTypeInfo()));//公众号认证类型 -1	未认证 0	微信认证 1	新浪微博认证 2	腾讯微博认 3	已资质认证通过但还未通过名称认 4	已资质认证通过、还未通过名称认证，但通过了新浪微博认证 5	已资质认证通过、还未通过名称认证，但通过了腾讯微博认证
            wxConfig.setWeixinNumber(wxOpenAuthorizerInfo.getAlias());//公众号所设置的微信号，可能为空
            wxConfig.setBusinessInfo(JSON.toJSONString(wxOpenAuthorizerInfo.getBusinessInfo()));//	用以了解功能的开通状况（0代表未开通，1代表已开通），详见business_info 说明
            wxConfig.setQrcodeimg(wxOpenAuthorizerInfo.getQrcodeUrl());//二维码图片的 URL，开发者最好自行也进行保存


            //没有授权就新增，授权过就修改
            WxConfig wxConfigResult = wxConfigService.selectWxConfigByJwid(jwid);

            if (wxConfigResult == null) {
                wxConfig.setId(UUIDGenerator.generate());
                wxConfig.setCreateTime(new Date());
                int resultInt = wxConfigService.insertWxConfig(wxConfig);
                if (resultInt > 0) {

                    JwSystemUserJwid jwSystemUserJwid = new JwSystemUserJwid();
                    jwSystemUserJwid.setUserId(Long.parseLong(userId));
                    jwSystemUserJwid.setJwid(jwid);
                    jwSystemUserJwid.setCreateTime(new Date());
                    JwSystemUserJwid jwSystemUserJwidResult = jwSystemUserJwidService.selectJwSystemUserJwidByJwid(jwid);

                    //当前公众号是否与用户关联
                    if (jwSystemUserJwidResult == null) {
                        jwSystemUserJwid.setId(UUIDGenerator.generate());
                        int resultInt2 = jwSystemUserJwidService.insertJwSystemUserJwid(jwSystemUserJwid);
                        logger.info("授权成功");
                        return AjaxResult.success("授权成功");
                    } else {
                        if (jwSystemUserJwidResult.getUserId() == (Long.parseLong(userId))) {
                            logger.info("重新授权成功");
                            return AjaxResult.success("重新授权成功");
                        } else {
                            logger.info("授权失败，公众号已经被其他用户授权");
                            return AjaxResult.success("授权失败，公众号已经被其他用户授权");
                        }
                    }
                }
            } else {
                wxConfig.setId(wxConfig.getId());
                wxConfigService.updateWxConfig(wxConfig);

                logger.info("更新授权信息，授权成功");
                return AjaxResult.success("更新授权信息，授权成功");
            }


        } catch (WxErrorException e) {
            logger.error("gotoPreAuthUrl", e);
            throw new RuntimeException(e);
        }
        logger.info("授权失败，未知原因");
        return AjaxResult.error("授权失败，未知原因");
    }

    @GetMapping("/get_authorizer_info")
    @ResponseBody
    public WxOpenAuthorizerInfoResult getAuthorizerInfo(@RequestParam String appId) {
        try {
            return wxOpenServiceDemo.getWxOpenComponentService().getAuthorizerInfo(appId);
        } catch (WxErrorException e) {
            logger.error("getAuthorizerInfo", e);
            throw new RuntimeException(e);
        }
    }


    /**
     * 构建网页授权用户授权获取用户信息
     */
    @GetMapping("/auth/buildOauth2Url")
    @ResponseBody
    public AjaxResult oauth2buildAuthorizationUrl() {
        String url = wxOpenServiceDemo.getWxOpenComponentService()
                .oauth2buildAuthorizationUrl("wx50c0c2bc15f2f944","http://open.aimengchong.cc/prod-api/wxauthapi/auth/get_user_authorizer_info","snsapi_userinfo","auth_user");
        return AjaxResult.success(url);
    }

    /**
     * 公众号网页授权-获取用户信息
     *
     * @param appid
     * @param code
     * @param state
     * @return
     */
    @GetMapping("/auth/get_user_authorizer_info")
    @ResponseBody
    public AjaxResult getUserAuthorizerInfo(@RequestParam String appid, @RequestParam String code, @RequestParam String state) {

        try {
            //第二步 通过 code 换取 access_token
            WxOAuth2AccessToken wxOAuth2AccessToken = wxOpenServiceDemo.getWxOpenComponentService().oauth2getAccessToken(appid, code);
            //第三步通过网页授权 access_token 获取用户基本信息（需授权作用域为 snsapi_userinfo）
            WxOpenMpService wxOpenMpService = wxOpenServiceDemo.getWxOpenComponentService().getWxMpServiceByAppid(appid);
            WxOAuth2Service wxOpenOAuth2Service = wxOpenMpService.getOAuth2Service();

            WxOAuth2UserInfo wxOAuth2UserInfo = wxOpenOAuth2Service.getUserInfo(wxOAuth2AccessToken, null);

            return AjaxResult.success(wxOAuth2UserInfo);

        } catch (WxErrorException e) {
            e.printStackTrace();

            return AjaxResult.error(e.getLocalizedMessage());
        }

    }
}
